package com.jy.rhin.application.infra;

import com.jy.rhin.application.infra.assembler.DocumentDtoAssembler;
import com.jy.rhin.application.infra.event.Event4DocumentEntry;
import com.jy.rhin.application.infra.event.Event4DocumentReference;
import com.jy.rhin.domain.document.content.DocumentContentDomainService;
import com.jy.rhin.domain.document.content.entity.DocumentContentDO;
import com.jy.rhin.domain.document.filter.DocumentFilterChain;
import com.jy.rhin.domain.document.filter.DocumentFilterContext;
import com.jy.rhin.domain.document.submission.DocumentSubmissionDomainService;
import com.jy.rhin.domain.document.submission.entity.DocumentSubmissionDO;
import com.jy.rhin.sdk.dto.document.DocumentContentDto;
import com.jy.rhin.sdk.dto.document.DocumentEntryDto;
import com.jy.rhin.sdk.dto.document.DocumentProvideAndRegisterDto;
import com.jy.rhin.sdk.dto.document.DocumentSubmissionSetDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author dhl
 */
@Slf4j
@Service
public class DocumentApplicationService {

    @Resource
    private DocumentFilterChain documentFilterChain;
    @Resource
    private ApplicationEventPublisher applicationEventPublisher;
    @Resource
    private DocumentContentDomainService documentContentDomainService;
    @Resource
    private DocumentSubmissionDomainService documentSubmissionDomainService;

    /**
     * 文档注册并提交
     * 1. 文档打包，保存文档
     * 2. 元数据打包，注册元数据
     *
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public DocumentProvideAndRegisterDto documentProvide(DocumentProvideAndRegisterDto dto) {
        DocumentFilterContext.init();
        documentFilterChain.provide(dto);
        List<DocumentContentDto> documents = dto.getDocuments();
        List<DocumentContentDO> documentContentDoList = DocumentDtoAssembler.buildContent(dto.getSubmissionSet(), documents);
        documentContentDomainService.saveDocumentContent(documentContentDoList);
        DocumentDtoAssembler.completeContentDto(dto, documentContentDoList);
        DocumentFilterContext.clear();
        //文档元索引获取
        for (DocumentEntryDto entryDto : dto.getSubmissionSet().getEntries()) {
            applicationEventPublisher.publishEvent(new Event4DocumentReference(entryDto.getRepositoryUniqueId(), entryDto.getUniqueId(), entryDto.getHomeCommunityId()));
        }
        return dto;
    }

    @Transactional(rollbackFor = Exception.class)
    public Long documentRegister(DocumentSubmissionSetDto submissionSet) {
        DocumentFilterContext.init();
        documentFilterChain.register(submissionSet);
        DocumentSubmissionDO submissionDO = DocumentDtoAssembler.buildSubmission(submissionSet);
        Long id = documentSubmissionDomainService.save(submissionDO);
        DocumentFilterContext.clear();
        applicationEventPublisher.publishEvent(new Event4DocumentEntry(id));
        return id;
    }

    @Transactional(rollbackFor = Exception.class)
    public Long documentUpdate(DocumentSubmissionSetDto submissionSet) {
        DocumentFilterContext.init();
        documentFilterChain.update(submissionSet);
        DocumentSubmissionDO submissionDO = DocumentDtoAssembler.buildSubmission(submissionSet);
        Long id = documentSubmissionDomainService.update(submissionDO);
        DocumentFilterContext.clear();
        applicationEventPublisher.publishEvent(new Event4DocumentEntry(id));
        return id;
    }

}
